
class Table(object):

    def __init__(self,keys=None,table=None) -> None:
        if isinstance(keys,list):
            self.keys = keys
        elif keys is None:
            self.keys = []
        else:
            raise ValueError("Error keys type")
        
        self.key2index = {k:v for v,k in enumerate(self.keys)}

        if table is None:
            self.From = []
            self.To = []
            self.Value = []
        elif self.__check_format(table):
            self.From, self.To, self.Value = table
        else:
            raise ValueError("Error table format")
    
    def __check_format(self,table) -> bool:
        if table is None:
            return True
        
        checker = (
            isinstance(table,list) and
            len(table) == 3 and
            len(table[0]) == len(table[1]) == len(table[2]) and
            all(0<=i<len(self.keys) for i in table[0]) and
            all(0<=j<len(self.keys) for j in table[1]) )
        return checker
    
    def view(self) -> None:
        print("key: "+", ".join(map(str,self.keys)))
        print("From\tTo\tValue")
        for L in zip(self.From,self.To,self.Value):
            print("{}\t{}\t{}".format(
                self.keys[L[0]], self.keys[L[1]], L[2]
                ))
    
    def add_key(self,*keys) -> None:
        for key in keys:
            if key in self.key2index:
                continue
            self.keys.append(key)
            self.key2index[key] = len(self.keys)-1
        
    def add_row(self,f,t,v=1,cheak_key=True) -> None:
        if cheak_key :
            self.add_key(f,t)
        self.From.append(self.key2index[f])
        self.To.append(self.key2index[t])
        self.Value.append(v)

def test_table():
    keys = ["A","B","C"]
    table = [[0,1,1,2],[2,1,2,0],[1,1,1,1]]
    table = Table(keys,table)
    table.view()
    table.add_row("B","D",3)
    table.view()

if __name__ == "__main__":
    test_table()